package com.link.base.base.questionnairesurvey.service;
/*
 * createdby: 刘鲁
 * created: 2018-07-04
 * comments:
 */

import com.alibaba.fastjson.JSONObject;
import com.link.base.base.enterprise.model.Enterprise;
import com.link.base.base.enterprise.service.EnterpriseService;
import com.link.base.base.mpconfig.model.Mp;
import com.link.base.base.mpconfig.service.MpService;
import com.link.base.base.mpconfig.service.MpTokenService;
import com.link.base.base.questionnairesurvey.dao.mybatis.mapper.AnswerMapper;
import com.link.base.base.questionnairesurvey.dao.mybatis.mapper.SurveyMapper;
import com.link.base.base.questionnairesurvey.model.*;
import com.link.base.base.user.model.User;
import com.link.base.base.user.service.LoginService;
import com.link.base.core.basic.util.YmlConstants;
import com.link.base.user.model.CoreUser;
import com.link.core.basic.controller.BasicControllerException;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.interceptor.SecurityInterceptor;
import com.link.core.basic.model.BasicModel;
import com.link.core.basic.query.QueryParams;
import com.link.core.basic.query.Sorter;
import com.link.core.basic.service.BasicServiceException;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.util.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;


/**
 * @author 刘鲁
 * @date 2018-07-04
 * @comments 问卷组织关系
 */
@Service
public class SurveyServiceImpl extends BasicServiceImpl<Survey> implements SurveyService {

    /**问卷接口调用类型 - 保存*/
    private static final String SURVEY_API_TYPE_SAVE = "save";
    /**问卷接口调用类型 - 提交*/
    private static final String SURVEY_API_TYPE_SUBMIT = "submit";

    /**
     * 是否过期
     **/
    private static final String SURVEY_STATUS_DISABLED = "Disabled";
    /**
     * 小程序用户登录类型
     **/
    private static final String LOGIN_TYPE_MP = "MP";
    @Resource
    private SurveyMapper surveyMapper;
    @Resource
    private SurveyService surveyService;
    @Resource
    private TopicService topicService;
    @Resource
    private TabService tabService;
    @Resource
    private AnswerService answerService;
    @Resource
    private SurveyUserService surveyUserService;
    @Resource
    private SurveyOrgService surveyOrgService;
    @Resource
    private MpService mpService;
    @Resource
    private MpTokenService mpTokenService;
    @Resource
    private EnterpriseService enterpriseService;
    @Resource
    private AnswerMapper answerMapper;
    @Resource
    private LoginService loginService;

    private static final String APIUSER = "APIUSER";

    @Override
    public BasicMapper<Survey> getBasicMapper() {
        return surveyMapper;
    }

    /**
     * 查询问卷详情
     *
     * @param entity
     * @return Survey
     * @throws Exception createdby: 刘鲁
     */
    @Override
    public Survey queryOneDetails(Survey entity) throws Exception {
        CoreUser user = UserUtil.getUser();
        if (user == null) {
            TokenUtils.setLogin(PropertyUtil.getCommonProperty("mock_unlogin_user"));
            user = UserUtil.getUser();
        }
        // 小程序用户是用acctId做关联的，其他类型是当前登录者id
//        if (null != user) {
//            if (StringUtils.equals(user.getLoginType(), LOGIN_TYPE_MP)) {
//                entity.setAcctId(user.getAcctId().toString());
//            } else {
//                entity.setAcctId(user.getId().toString());
//            }
//        }

        Survey survey = this.queryById(entity.getId());
        if (survey == null) {
            throw new BasicServiceException("获取问卷失败，请确认问卷是否存在！");
        }

        Topic topic = new Topic();
        QueryParams qps = new QueryParams();
        qps.setPageFlag(false);
        qps.addSorter(new Sorter("sequence", Sorter.DIR_ASC));
        topic = (Topic) BasicModel.transformClass(topic, qps);

        topic.setSurveyId(survey.getId());
        List<Topic> topicList = topicService.queryByExamplePage(topic);
        survey.setTopicList(topicList);
        Tab tab = new Tab();
        tab = (Tab) BasicModel.transformClass(tab, qps);
        for (Topic arr : topicList) {
            tab.setTopicID(arr.getId().toString());
            List<Tab> tabList = tabService.queryByExamplePage(tab);
            arr.setTabList(tabList);
        }
        //是否获取答案
        String flag = "Y";
        if (flag.equals(entity.getAttr6())) {
            Answer answer = new Answer();
            answer.setPageFlag(false);
            //传试卷人是否为空
            if (StringUtils.isNull(entity.getAttr7())) {
                answer.setEmpId(user.getId());
            } else {
                answer.setEmpId(Long.parseLong(entity.getAttr7()));
            }

            for (Topic arr : topicList) {
                answer.setTopicID(arr.getId());
                arr.setAnswerList(answerService.queryByExamplePage(answer));
            }
        }
        return survey;
    }

    /**
     * 保存修改试卷
     *
     * @param survey
     * @throws Exception createdby: 刘鲁
     */
    @Override
    @Transactional(rollbackFor = BasicServiceException.class)
    public Survey SaveSurvey(Survey survey) throws Exception {
        if (StringUtils.isNull(survey.getTitleSurvey())) {
            throw new BasicServiceException("请填写问卷名！");
        }
        Long surveyId = survey.getId();
        if (survey.getId() == null) {
            surveyService.insert(survey);
        } else {
            Survey querytmp = new Survey();
            querytmp.setId(survey.getId());
            Survey s = surveyService.queryById(querytmp);
            if (s == null) {
                surveyService.insert(survey);
                return queryById(survey);
            }
            Survey surveyRaw = surveyService.queryOneDetails(survey);
            List<Topic> topicList = surveyRaw.getTopicList();
            for (Topic old : topicList) {
                topicService.deleteById(old);
            }
            surveyService.update(survey);
            List<Topic> newTopicList = survey.getTopicList();
            for (Topic arr : newTopicList) {
                arr.setSurveyId(surveyId);
                topicService.insert(arr);
            }
        }
        return queryById(survey);
    }

    /**
     * 插入问卷时插入题目
     *
     * @param entity
     * @throws Exception createdby: 刘鲁
     */
    @Override
    @Transactional(rollbackFor = BasicServiceException.class)
    public void afterInsert(Survey entity) throws Exception {
        List<Topic> topicList = entity.getTopicList();
        if (!CollectionUtils.isEmpty(topicList)) {
            for (Topic arr : topicList) {
                arr.setSurveyId(entity.getId());
                topicService.insert(arr);
            }
        }
    }


    /**
     * 提交问卷
     *
     * @param surver
     * @throws Exception createdby: 刘鲁
     */
    @Override
    @Transactional(rollbackFor = BasicServiceException.class)
    public void submitSurvey(Survey surver) throws Exception {

        //h5页面可能没有账套id
        if (UserUtil.getUser() == null) {
            TokenUtils.setLogin(PropertyUtil.getCommonProperty("mock_unlogin_user"));
        }
        //修改试卷作答信息
        CoreUser user = UserUtil.getUser();
        // 校验问卷头是否存在
        Survey sur = surveyService.queryById(surver);
        if (Objects.isNull(sur)) {
            throw new BasicServiceException("操作问卷不存在，请核实");
        }
        if (StringUtils.equals(sur.getState(), SURVEY_STATUS_DISABLED)) {
            throw new BasicServiceException("问卷已失效，无法提交！");
        }
        if (StringUtils.isNotBlank(sur.getEndTime())) {
            String end = sur.getEndTime().trim();
            Date endTime = DateUtil.attemptStringToDate(sur.getEndTime());
            if ((!DateUtil.dateToStr(new Date(), DateUtil.DAY).equals(end)) && endTime.before(new Date())) {
                sur.setState("Disabled");
                surveyService.update(sur);
                throw new BasicServiceException("问卷有效时间已过，无法提交！");
            }
        }
        // 问答列表
        List<Topic> topicList = surver.getTopicList();
        for (Topic arr : topicList) {
            List<Answer> answerList = arr.getAnswerList();
            if ("Y".equals(arr.getRequiredFlag())) {
                if (CollectionUtils.isEmpty(answerList)) {
                    throw new BasicServiceException("必答题必须填写！");
                }
            }
        }

        // 清空原有答案
        cleadOriginalAnswer(surver, user);

        for (Topic arr : topicList) {
            List<Answer> answerList = arr.getAnswerList();
            if (!CollectionUtils.isEmpty(answerList)) {
                answerService.batchInsert(answerList);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = BasicServiceException.class)
    public void saveSurveyAnswer(Survey surver) throws Exception {
        //h5页面可能没有账套id
//        if (UserUtil.getUser() == null) {
//            setLogin(APIUSER);
//        }
        // 校验问卷头是否存在
        Survey sur = surveyService.queryById(surver);
        if (Objects.isNull(sur)) {
            throw new BasicServiceException("操作问卷不存在，请核实");
        }
        if (StringUtils.equals(sur.getState(), SURVEY_STATUS_DISABLED)) {
            throw new BasicServiceException("问卷已失效，无法提交！");
        }
        if (StringUtils.isNotBlank(sur.getEndTime())) {
            String end = sur.getEndTime().trim();
            Date endTime = DateUtil.attemptStringToDate(sur.getEndTime());
            boolean surveyTimeOut = (!DateUtil.dateToStr(new Date(), DateUtil.DAY).equals(end)) && endTime.before(new Date());
            if (surveyTimeOut) {
                sur.setState("Disabled");
                surveyService.update(sur);
                throw new BasicServiceException("问卷有效时间已过，无法提交！");
            }
        }
        // 问答列表
        List<Topic> topicList = surver.getTopicList();
        for (Topic arr : topicList) {
            List<Answer> answerList = arr.getAnswerList();
            if (!CollectionUtils.isEmpty(answerList)) {
                answerService.batchInsert(answerList);
            }
        }
    }


    /**
     * 发布问卷
     *
     * @param entity
     * @throws Exception createdby: 刘鲁
     */
    @Override
    @Transactional(rollbackFor = BasicServiceException.class)
    public void issueSurvey(Survey entity) throws Exception {
        Survey sur = surveyService.queryById(entity);
        if (sur == null) {
            entity.setState("New");
            SaveSurvey(entity);
        }
        sur = surveyService.queryById(entity);
        String flag = "Y";
        if (!StringUtils.equals(entity.getHandleFlag(), flag)) {
            SurveyOrg queryOrg = new SurveyOrg();
            queryOrg.setSurveyId(entity.getId());
            queryOrg.setLoginCorpId(sur.getLoginCorpId());
            queryOrg.setPageFlag(false);
            List<SurveyOrg> surveyOrgList = surveyOrgService.queryByExamplePage(queryOrg);
            String newStr = "New";
            if (!newStr.equals(sur.getState())) {
                throw new BasicServiceException("问卷已发布或已失效，无法发布！");
            }
            if (StringUtils.isNull(sur.getStartTime())) {
                throw new BasicServiceException("有效开始时间不能为空！");
            }
            //若没有选发布的组织，则选择所有组织
            if (CollectionUtils.isEmpty(surveyOrgList)) {
                throw new BasicServiceException("发布的组织不能为空！");
            }

            for (SurveyOrg org : surveyOrgList) {
                SurveyUser queryUser = new SurveyUser();
                queryUser.setOrgId(org.getOrgId());
                queryUser.setPageFlag(false);
                List<User> userList = surveyUserService.queryAllUserExamplePage(queryUser);
                for (User u : userList) {
                    SurveyUser s = new SurveyUser();
                    s.setId(keyGenerateService.keyGenerate());
                    s.setSurveyId(entity.getId());
                    s.setEmpId(u.getId());
                    s.setFillInStatus("No");
                    surveyUserService.insert(s);
                }
            }
        }
        sur.setState("Published");
        surveyService.update(sur);
    }

    /**
     * 删除试卷时删除题目
     *
     * @param entity
     * @throws Exception createdby: 刘鲁
     */
    @Override
    @Transactional(rollbackFor = BasicServiceException.class)
    public void beforDelete(Survey entity) throws Exception {
        //删除题目
        Topic topic = new Topic();
        topic.setSurveyId(entity.getId());
        topic.setPageFlag(false);
        List<Topic> topicList = topicService.queryByExamplePage(topic);
        for (Topic arr : topicList) {

            topicService.deleteById(arr);
        }
        //删除问卷与用户关联
        SurveyUser surveyUser = new SurveyUser();
        surveyUser.setSurveyId(entity.getId());
        surveyUser.setPageFlag(false);
        List<SurveyUser> surveyUserList = surveyUserService.queryByExamplePage(surveyUser);
        for (SurveyUser arr : surveyUserList) {
            surveyUserService.deleteById(arr);
        }

    }

    /**
     * 生成问卷二维码
     * @param survey
     * @return Map
     * @throws Exception
     */
    @Override
    public Map<String, Object> createMiniprogramCode(Survey survey) throws Exception {
        Mp mp = new Mp();
        //主要
        mp.setMainFlag("Y");
        //有效
        mp.setValidFlag("Y");
        List<Mp> reMp = mpService.queryAll(mp);
        if (CollectionUtils.isEmpty(reMp)) {
            throw new BasicServiceException("操作小程序配置信息不存在");
        }
        Mp mpResult = reMp.get(0);
        String accesstoken = mpTokenService.getMpAccessToken(mpResult);
        String requestUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accesstoken;
        // 转换成特定格式字符串
        URL url = new URL(requestUrl);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        // 提交模式
        httpURLConnection.setRequestMethod("POST");
        httpURLConnection.setDoOutput(true);
        httpURLConnection.setDoInput(true);
        JSONObject paramJson = new JSONObject();
        paramJson.put("scene", survey.getId());
        paramJson.put("path", "pages/questionnaire/question-detail");
        paramJson.put("width", 430);
        paramJson.put("auto_color", true);
        String data = JsonUtil.toString(paramJson);
        PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
        printWriter.write(data);
        printWriter.flush();
        //返回的图片流
        BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream());
        String preFileName = "survey_" + survey.getId();
        //图片路径
        String realativPath = "/web/file/" + preFileName + "/" + DateUtil.dateToStr(new Date(), "yyyyMMddHHmmss") + ".jpg";
        String codeUrl = YmlConstants.getPortalShareFileDir() + realativPath;
        //图片文件夹目录路径
        String outUrl = YmlConstants.getPortalShareFileDir() + "/web/file/" + preFileName;
        //
        File outDir = new File(outUrl);
        if (!outDir.exists()) {
            outDir.mkdirs();
        }
        OutputStream os = null;
        Map<String, Object> map = new HashMap<>(8);
        try {
            os = new FileOutputStream(codeUrl);
            int len;
            byte[] arr = new byte[1024];
            while ((len = bis.read(arr)) != -1) {
                os.write(arr, 0, len);
                os.flush();
            }
            os.close();
        } catch (Exception e) {
            e.getMessage();
            throw new Exception(e.getMessage());
        } finally {
            if (null != os) {
                os.close();
            }
        }
        map.put("Url", YmlConstants.getPortalShareUrlDir() + realativPath);
        return map;

    }

//    @Override
//    public void submitSurveyByH5(Survey surver) throws Exception {
//        //h5页面可能没有账套id
//        if (UserUtil.getUser() == null) {
//            setLogin(APIUSER);
//        }
//        //修改试卷作答信息
//        CoreUser user = UserUtil.getUser();
//        // 校验问卷头是否存在
//        Survey sur = surveyService.queryById(surver);
//        if (Objects.isNull(sur)) {
//            throw new BasicServiceException("操作问卷不存在，请核实");
//        }
//        if (StringUtils.equals(sur.getState(), SURVEY_STATUS_DISABLED)) {
//            throw new BasicServiceException("问卷已失效，无法提交！");
//        }
//        if (StringUtils.isNotBlank(sur.getEndTime())) {
//            String end = sur.getEndTime().trim();
//            Date endTime = DateUtil.attemptStringToDate(sur.getEndTime());
//            if ((!DateUtil.dateToStr(new Date(), DateUtil.DAY).equals(end)) && endTime.before(new Date())) {
//                sur.setState("Disabled");
//                surveyService.update(sur);
//                throw new BasicServiceException("问卷有效时间已过，无法提交！");
//            }
//        }
//        // 问答列表
//        List<Topic> topicList = surver.getTopicList();
//        if (!SURVEY_API_TYPE_SAVE.equals(surver.getAttr5())) {
//            // 保存时候不校验必输
//            for (Topic arr : topicList) {
//                List<Answer> answerList = arr.getAnswerList();
//                if ("Y".equals(arr.getRequiredFlag())) {
//                    if (CollectionUtils.isEmpty(answerList)) {
//                        throw new BasicServiceException("必答题必须填写！");
//                    }
//                }
//            }
//        }
//        cleadOriginalAnswer(surver, user);
//
//        for (Topic arr : topicList) {
//            List<Answer> answerList = arr.getAnswerList();
//            if (!CollectionUtils.isEmpty(answerList)) {
//                answerService.batchInsert(answerList);
//            }
//        }
//    }

    /**
     * @author HuangLJ
     * @param params 用户登录信息
     * @date 2018/11/12 7:15 PM
     * 通过传入的参数查询出用户和企业，放入线程里面。
     */
    private void setLogin(String... params) {
        if (params != null && params.length > 0) {
            try {
                String userName = params[0];


                //把内部token写入到线程缓存里面
                SecurityInterceptor.token.set(SecurityInterceptor.INTERNAL_TOKEN.concat(":").concat(userName));

                User user = loginService.getUser(userName, "");

                if (StringUtils.isNull(user.getCurClientId())) {
                    user.setCurClientId("public");
                }
                SecurityInterceptor.tempUser.set(user);

                Enterprise enterprise = enterpriseService.queryByCode(user.getCorpid());
                SecurityInterceptor.tempEnterpirse.set(enterprise);
            } catch (Exception e) {
                throw new BasicControllerException(e.getMessage());
            }
        }
    }

    /**
     * 清除原有答案
     *
     * @author NingLanhao
     * @date 2019-07-16 16:59
     * @param survey 包含问卷id
     * @param user 当前登录用户
     * @return void
     */
    private void cleadOriginalAnswer(Survey survey, CoreUser user) throws Exception {
        survey.setAttr6("Y");
        Survey surveyWithAllAnswer = queryOneDetails(survey);
        for (Topic arr : surveyWithAllAnswer.getTopicList()) {
            List<Answer> answerList = arr.getAnswerList();
            if (CollectionUtils.isEmpty(answerList)) {
                continue;
            }
            for (Answer answer : answerList) {
                if (null == answer.getEmpId()) {
                    answer.setEmpId(user.getId());
                }
                //清空原有答案
                answerMapper.deleteByTopic(answer);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Survey copyFromTemplate(Survey survey) throws Exception {
        Survey templateSurvey = this.queryOneDetails(survey);
        // 从模板中复制一个回访问卷
        Long surveyId = keyGenerateService.keyGenerate();
        templateSurvey.setId(surveyId);
        templateSurvey.setState("New");
        templateSurvey.setSurveySource("FollowUp");
        templateSurvey.setSurveyKind("Questionnaire");
        List<Topic> topicList = templateSurvey.getTopicList();
        Map<String, String> idMap = new HashMap<>(topicList.size());
        for (Topic topic : topicList) {
            Long oldTopicId = topic.getId();
            Long newTopicId = keyGenerateService.keyGenerate();
            topic.setId(newTopicId);
            topic.setSurveyId(surveyId);
            topic.setShowFlag("Y");
            List<Tab> tabList = topic.getTabList();
            idMap.put(oldTopicId.toString(), newTopicId.toString());
            for (Tab tab : tabList) {
                Long newId = keyGenerateService.keyGenerate();
                tab.setId(newId);
                tab.setTopicID(newTopicId.toString());
            }
            topic.setTabList(tabList);
        }
        //遍历修改nextTopicId.
        for (Topic topic : topicList) {
            List<Tab> tabList = topic.getTabList();
            for (Tab tab : tabList) {
                //跳题id修改
                String originalNextId = tab.getNextTopicId().toString();
                if (StringUtils.isNotBlank(originalNextId) && !"next".equals(originalNextId)
                        && !"end".equals(originalNextId)) {
                    String newNextTopicId = idMap.get(originalNextId);
                    if (StringUtils.isBlank(newNextTopicId)) {
                        throw new BasicServiceException("跳题id有误");
                    }
                    tab.setNextTopicId(newNextTopicId);
                }
            }
        }
        templateSurvey.setTopicList(topicList);
        Survey result = this.SaveSurvey(templateSurvey);
        return result;
    }

    /**
     * 模板复制到互动活动时替换跳题id
     * @return
     * @throws Exception
     */
    @Override
    public Survey replaceNextTopicId(Survey survey) throws Exception {
        List<Topic> topicList = survey.getTopicList();
        //新旧idMap，用于放在选项上
        Map<String, String> idMap = new HashMap<>(topicList.size());
        //获取map信息
        for (Topic topic : topicList) {
            //id写入oldId中
            topic.setOldId(topic.getId());
            //新生成id
            topic.setId(keyGenerateService.keyGenerate());
            idMap.put(topic.getOldId().toString(), topic.getId().toString());
        }
        //遍历修改选项
        for (Topic topic : topicList) {
            List<Tab> tabList = topic.getTabList();
            for (Tab tab : tabList) {
                //写入id
                tab.setId(keyGenerateService.keyGenerate());
                //跳题id修改
                if (StringUtils.isNotBlank(tab.getNextTopicId()) && !"next".equals(tab.getNextTopicId())
                        && !"end".equals(tab.getNextTopicId())) {
                    String nextTopicId = idMap.get(tab.getNextTopicId());
                    if (StringUtils.isBlank(nextTopicId)) {
                        throw new BasicServiceException("跳题id有误");
                    }
                    tab.setNextTopicId(nextTopicId);
                }
            }
        }
        return survey;
    }
}
